﻿/** ************************* Ccay IGrid Tree ********************************** */
(function(IGrid, Const) {
	// 国际化信息
	var treeMsg = Const.I18n.rowRender = {
		btnAddChildNode : "ccay.common.button.addChildNode",
		btnAddSameLevelNode : "ccay.common.button.addSameLevelNode",
		btnCopySameLevelNode : "ccay.common.button.copySameLevelNode",
		btnDeleteNode : "ccay.common.button.deleteNode",
		btnLoadChild: "ccay.common.button.reLoad"
	};

	/** 注册树形行渲染器 */
	IGrid.rowRender.add("tree", {
		/** @description 创建树表插件
		 *  @param {Object} grid IGrid对象
		 *  @param {Object} op grid的配置信息
		 */
		build : function(grid, op) {
			// 不更新滚动位置
			op.autoScroll = false;
			// 设置缓存标示
			//op._cache = true;
			// 设置是否动态延迟加载
			op.lazyLoad = "filter";
			var rOp = op.rowRenderOp;
			// 若设置请求，则是列延迟加载
			(rOp.ajax || rOp.url) && (rOp.lazyLoad = true);
			// 设置加载深度
			(rOp.loadDeep != null) || (rOp.loadDeep = Ccay.UI.Config.igrid.treeLoadDeep);
			// 添加列设置
			op.handler.setColumn.add(this.colSet);
			// 添加绑定树形数据
			op.handler.dataProcess.add(treeGrid.buildTreeData);
			// 注册点击事件
			op.handler.click.add("toggleTree", treeGrid.toggleTree);
			// 注册排序方法
			op.fnSort || (op.fnSort = treeGrid.sort);
			// 旧的数据
			var dataset = op._treeStorage ? op._treeStorage.dataset : null;
			// 创建树形数据仓库
			op._treeStorage = Ccay.Storage.createDataTree({
				parentKey : rOp.parent,
				nodeKey : rOp.field
			});
			// 旧的数据赋值到仓库中
			dataset && (op._treeStorage.dataset = dataset);
			this.initTreeTirgger(grid, op.Storage, op._treeStorage);
			// 初始化操作设置
			this.initOperation(grid, op);
			// 重新初始化时，不执行
			this.extendStorage(grid, op.Storage, op._treeStorage);
		},
		initTreeTirgger: function (grid, storage, treeStorage) {
			var op = grid.op, storeTrigger = storage.Trigger, treeTrigger = treeStorage.Trigger;
			// 添加删除数据后，取消全选状态
			storeTrigger.remove.add(function (item, delStatus, tr) {
				if (tr.data("_isRemove")) {
					tr.removeData("_isRemove");
				} else {
					tr.data("_selected", {"all": false});
					treeGrid.selectParent(grid, op, tr, true, false);
				}
			});
			// 添加新增数据的状态
			treeTrigger.insert.add(function(node, parent) {
				treeGrid.initNodeStatus(op, node.data, parent);
			});
			// 添加半选数据的状态
			treeTrigger.halfSelect.add(function(item, selected, tr) {
				tr && tr.toggleClass(Const.halfSelected.css, selected);
			});
		},
		initOperation : function(grid, op) {
			var rOp = op.rowRenderOp, operation = op.operation;
			if (operation || rOp.lazyLoad) {
				// 开启上下文菜单
				op.contextMenu = true;
				// 初始化上下文菜单设置
				op.menuOp || (op.menuOp = {});
				op.menuOp.menus || (op.menuOp.menus = []);
				if (operation) {
					// 初始化新增的默认数据
					var insertOp = operation.insert;
					if (insertOp) {
						// 清除新增行内置数据
						insertOp.clear || (insertOp.clear = []);
						insertOp.clear.push("_hasChild", "_lazyLoad", "_opened", "_childCount", "_parents", rOp.field);
						// 新增时，只新增一条数据
						insertOp.copy = false;
						// 设置新增行的位置
						insertOp._getInsertSet = function (grid,op) {
							return {
								posTr: grid.getDataBody().children(':not(.igrid-newrow):first'), 
								posIndex: 0
							};
						}
					}
					// 处理是否只获取删除的有效父节点
					if (operation.save && rOp.delRoot) {
						var setAjax = operation.save.ajax.setAjax;
						operation.save.ajax.setAjax = function(ajax) {
							if (ajax.data && ajax.data.items2Delete.length) {
								ajax.data.items2Delete = treeGrid.getRoots(ajax.data.items2Delete, op);
							}
							setAjax && setAjax(ajax);
						}
					}
				}
			}
		},
		extendStorage : function(grid, storage, treeStorage) {
			// treeStorage的重载
			treeStorage.extend({
				setNodeStatus:function(node,name,status){
			    	if(node = this.at(node)){
			    		var tempNodeData = node.data;
				    	this.setStatus(tempNodeData,name,status);
				    	// 若存在子节点，则将全部子节点选中标示，否则将标示清空
						if (tempNodeData._childCount) {
							tempNodeData._selectedChilds = status ? tempNodeData._childCount : 0;
						}
				    	this.each(function(item){
				    		this.setStatus(item,name,status);
				    		// 若存在子节点，则将全部子节点选中标示，否则将标示清空
							if (item._childCount) {
								item._selectedChilds = status ? item._childCount : 0;
							}
				    	},node);
			    	}
			    	return this;
			    },
			    toggleNode:function(node,open){
			    	if(node = this.at(node)) {
			    		if(node.count){
				    		this.setStatus(node.data,"_opened",open);
				    		if(open){
				    			var newChilds = [],
				    				childs = this.getChilds(node,function(item, iNode, i){
				    				if(this.isNew(item) && (item._tempPos != "last"))
				    				{
				    					newChilds.push(item);
				    					return false;
				    				}
				    				else if(!this.isOpened(item))
				    					return this.ReturnValue.next;
				    				else 
				    				return true;
				    			});
				    			// 将新增数据插入到相应位置
				    			return treeGrid.insertToChilds(node.data, newChilds, childs, this);
				    		}
			    		}
			    	}
			    	return [];
			    }
			});
			if (!grid.op._reIniting) {
				// 扩展数据仓库
				storage.extend({
					filter : function(fields, fnFilter, copy) {
						var records = treeStorage.filter(fields, fnFilter, copy);
						if (this.insertStorage && this.insertStorage.len())
							return records.concat(this.insertStorage.getInsertedRecords(fields, fnFilter, true));
						return records;
					},
					mergeNewData : function(merge, op) {
						var insertStore = this.insertStorage;
						if (insertStore && insertStore.len()) {
							if (merge) {
								var arr = [], store = this, treeStore = op._treeStorage, dataset,
									pid, parent, parentPos, dataKey, dataPos, tempPos;
								insertStore.each(function(item, i) {
									delete item._newIndex;
									delete item._seq;
									parent = dataPos = null;
									pid = treeStore.getParentKey(item);
									if (item._index) {
										tempPos = item._tempPos;
										dataset = store.dataset;
										for (var i = 0, data; data = dataset[i]; i++) {
											dataKey = treeStore.getKey(data);
											// 获取父节点，并缓存父节点的位置
											if (!parent && dataKey == pid) {
												parent = data;
												parentPos = i;
												if (!tempPos)
													break;
											}
											// 插入节点到dom中
											if (parent) {
												if (parent._opened) {
													// 获取节点ID
													if (tempPos == dataKey) {
														dataPos = i;
														break;
													} else if (tempPos == "last" && parent != data && data._deep != item._deep) {
														dataPos = i;
														break;
													}
												} else {
													break;
												}
											}
										}
										// 插入节点到dom中
										if (parent && parent._opened) {
											store.fn.insertItem.call(store, item, tempPos ? dataPos : parentPos + 1);
										}
									} else
										store.fn.insertItem.call(store, item, -item.rowIdx - 1);
									// 节点不存在在dom数据集中，则在tree数据集中查找
									if (!parent) {
										parent = treeStore.findOne(function(data, node, i) {
											return (treeStore.getKey(data) == pid) ? true : false;
										});
									}
									// 插入节点到数据集中
									treeStore.insertItem(parent, item);
								});
							}
							insertStore.clear();
						}
					}
				});
			}
		},
		// 设置节点列
		colSet : function(grid, col, op) {
			var rOp = op.rowRenderOp;
			if (col.field == rOp.showField) {
				col.cssName = "tree-cell " + (col.cssName || '');
				op.rowAttr.deep = "${#_deep}";
				// tree节点默认使用子渲染器
				if (!col.renderer || !col.renderer.type)
					col.renderer = Ccay.UI.Renderer.get("childRender");
				// 设置tree的编号字段
				if (op.showSeq) {
					var seqCol = op.columns[0];
					seqCol.content = "<span>${#data._seq || index}</span>";
					seqCol.cssName += " tree-seq";
				}
				treeGrid.buildNodeTmpl(col, op.rowRenderOp, op);
				// 初始化上下文菜单按钮
				if (op.operation || rOp.lazyLoad) {
					treeGrid.initTreeEdit(grid, col, op);
				}
			}
		},
		clear : function(grid, op) {
			// 清除上下文菜单配置
			delete op.menuOp;
			if (op.columns) {
				// 遍历删除节点列的内容及样式
				$.each(op.columns, function(i, col) {
					if (!col.inner && col.field == op.rowRenderOp.showField) {
						col.content = null;
						col.cssName = null;
						return false;
					}
				});
			}
		}
	});

	var treeGrid = IGrid.tree = {
		buildTreeData : function(op) {
			if (!op._scrollLoading) {
				var loadDeep = op.rowRenderOp.loadDeep,
					dataFilter = op._treeIniting ? op._treeStorage : op._treeStorage.store(this),
					data = dataFilter.filterByDeep(op.rowRenderOp.loadDeep, function(item, node) {
								if (node.count) {
									item._opened = (item._deep < loadDeep);
									item._childCount = node.count;
								}
							});
				op.Storage.store(data);
				op._treeIniting && (delete op._treeIniting);
				return data;
			}
			dynamicLoad.updateTotal(op);
			return this;
		},
		initNodeStatus : function(op, data, parent) {
			var rOp = op.rowRenderOp,
			// showSeq = op.showSeq && rOp.treeSeq,
			parentData = parent.data, storage = op._treeStorage;
			// 设置节点状态
			if (!storage.isNew(data)) {
				if (rOp.fnCheckChild ? rOp.fnCheckChild(data) : rOp.lazyLoad)
					data._lazyLoad = data._hasChild = 1;
			}
			// showSeq && (data._seq = parent.count);
			if (parentData) {
				// 更新父节点状态
				if (!parentData._hasChild) {
					parentData._hasChild = 1;
					delete parentData._lazyLoad;
				}

				if (storage.isSelected(parentData))
					data[storage.Status.selected] = true;
				else if (storage.isDeleted(parentData))
					data[storage.Status.deleted] = true;
			}
		},
		// 处理原始数据,tree的lazyLoad模式下
		dataBuild : function(op) {
			if (!op._scrollLoading) {
				var datas = this, rOp = op.rowRenderOp, checkChild = rOp.fnCheckChild;
				// showSeq = op.showSeq && rOp.treeSeq;
				for (var i = 0, data; data = datas[i]; i++) {
					data._lazyLoad = data._hasChild = checkChild ? checkChild(data) : 1;
					data._deep = 0;
					// showSeq && (data._seq = i+1);
				}
				// op.dataset = datas;
				return datas;
			}
			return this;
		},
		getID : function(field, data) {
			return Ccay.DataHelper.getObj(field, data);
		},
		// 生成数型数据
		buildDataTree : function(datas, op) {
			var arrRoot = [], field = op.rowRenderOp.field, pField = op.rowRenderOp.parent, node = datas.shift(), root;

			while (node) {
				var pid = this.getID(pField, node);

				if (this.checkParent(pid, node, op, datas))
					root = treeGrid.getParent(pid, node, datas, field, pField);
				else {
					root = node;
					treeGrid.getChild(root, datas, field, pField);
				}
				arrRoot.push(root);
				node = datas.shift();
			}
			return arrRoot;
		},
		// 判断父数据
		checkParent : function(pid, node, op, datas) {
			var fnCheckRoot = op.rowRenderOp.fnCheckRoot;
			if (fnCheckRoot && fnCheckRoot(pid, node, datas)) {
				return true;
			}
			return pid && pid > 0;
		},
		// 获取数据的父数据
		getParent : function(pid, node, datas, field, pField) {
			for (var i = 0, data; data = datas[i]; i++) {
				if (treeGrid.getID(field, data) == pid) {
					datas.splice(i, 1);
					--i;
					data._childs = [node];
					pid = treeGrid.getID(pField, data);
					treeGrid.getChild(data, datas, field, pField);
					return pid ? arguments.callee(pid, data, datas, field, pField) : data;
				}
			}
			return node;
		},
		// 获取数据的子数据
		getChild : function(node, datas, field, pField) {
			var pid = treeGrid.getID(field, node);
			if (pid) {
				for (var i = 0, data; data = datas[i]; i++) {
					if (treeGrid.getID(pField, data) == pid) {
						datas.splice(i, 1);
						--i;
						node._childs ? node._childs.push(data) : node._childs = [data];
					}
				}
				// 查询子的子节点
				if (node._childs && node._childs.length) {
					for (var i = 0, child; child = node._childs[i]; i++) {
						arguments.callee(child, datas, field, pField);
					}
				}
			}
		},
		// 将树结构对象转化成数据对象
		buildTreeList : function(datas, rOp) {
			// var showSeq = rOp.treeSeq;
			var list = [], deep = 0;
			for (var i = 0, node; node = datas[i]; i++) {
				// this.checkChild(node,list,deep,rOp,showSeq ? i+1 :
				// null,cacheData);
				this.checkChild(node, list, deep, rOp)
			}
			return list;
		},
		// 判断子项数据，并加到数组上,非缓存时，不做状态初始化
		checkChild : function(node, list, deep, rOp, seq) {
			list.push(node);
			// 处理子数据
			var childs = node._childs;
			if (childs) {
				this.addTreeRow(childs, list, ++deep, rOp);
				delete node._childs;
			}
		},
		// 添加树的行数据
		addTreeRow : function(childs, list, deep, op) {
			for (var j = 0, node = childs[0]; node; j++, node = childs[j]) {
				// this.checkChild(node,list,deep,op, seq ? seq+'.'+ (j+1) :
				// null);
				this.checkChild(node, list, deep, op);
			}
		},
		// 树节点的隐藏和显示子项
		toggleTree : function(e, trigger, grid) {
			e.stopPropagation();
			trigger.toggleClass('tree-close');
			dynamicLoad.loadChild(trigger, grid);
		},
		// 数据编辑操作
		initTreeEdit : function(grid, col, op) {
			var rOp = op.rowRenderOp, menus = op.menuOp.menus;
			// 延迟加载节点时，显示重新加载节点按钮
			if (rOp.lazyLoad) {
				menus.push({
					text : $i18n(treeMsg.btnLoadChild),
					css : 'load_child',
					click : function(cell) {
						// 是否将搜索数据带入请求
						if (rOp.allowSearch && op.ajax && op.ajax.data) {
							rOp.ajax.data = op.ajax.data;
						}
						// 重新加载子节点
						treeGrid.reloadChildNodes(grid, grid.getRowData(cell));
					},
					fnCheck : function(cell, menu, data) {
						return data && !data._inserted && data._hasChild;
					}
				});
			}
			if (op.operation) {
				if (op.operation.insert) {
					var row = op.operation.insert.defaultRow.data, addRoot = rOp.addRoot;
					row._deep = 0;
					row._hasChild = null;
					row._lazyLoad = null;
					// 复制同级项
					menus.push({
						text : $i18n(treeMsg.btnCopySameLevelNode),
						css : 'copy',
						click : function(cell) {
							treeGrid.insertNode(cell, op, grid, false, true);
						},
						fnCheck : function(cell, menu, data) {
							return data && (data._deep > 0 || addRoot) && !data._deleted;
						}
					});
					// 新增同级项
					menus.push({
						text : $i18n(treeMsg.btnAddSameLevelNode),
						css : 'add',
						click : function(cell) {
							treeGrid.insertNode(cell, op, grid);
						},
						fnCheck : function(cell, menu, data) {
							return data && (data._deep > 0 || addRoot) && !data._deleted;
						}
					});
					// 新增子项
					menus.push({
						text : $i18n(treeMsg.btnAddChildNode),
						css : 'add_child',
						click : function(cell) {
							treeGrid.insertNode(cell, op, grid, true);
						},
						fnCheck : function(cell, menu, data) {
							return data && !data._inserted && (!rOp.maxDeep || data._deep < rOp.maxDeep) && !data._deleted;
						}
					});
				}
				if (op.operation.del) {
					// 删除&撤销删除
					menus.push({
						text : $i18n(treeMsg.btnDeleteNode),
						css : 'remove',
						click : function(cell) {
							treeGrid.removeNode(cell, op, grid);
						}
					});
				}
				menus.length && (col.menuable = true);
			}
		},
		// 新增树节点
		insertNode : function(cell, op, grid, isChild, isCopy) {
			var tr = grid.getCellRow(cell), rowData = grid.getRowData(tr);
			if (rowData) {
				var rOp = op.rowRenderOp, deep = rowData._deep + (isChild ? 1 : 0), 
					endTr = this.getPosTr(tr.next(), deep, isChild),
					data = $.extend({}, isCopy ? rowData : op.operation.insert.defaultRow.data),
					dataHelper = Ccay.DataHelper, isSelectParent;
				// 复制数据时，将clear的数据清除
				isCopy && IGrid.Operation.insert.clearField(op, data, op.operation.insert);
				data = $.extend(true, {}, data);
				data._deep = deep;
				// 若存在parentText，则将父节点的名称赋给新增数据的parentText属性
				if (rOp.parentText) {
					var parentText = isChild ? dataHelper.getObj(rOp.showField, rowData) : dataHelper.getObj(rOp.parentText, rowData);
					dataHelper.setObj(rOp.parentText, data, parentText);
				}
				// 设置新增数据的父ID
				dataHelper.setObj(rOp.parent, data, this.getID(isChild ? rOp.field : rOp.parent, rowData));
				IGrid.Operation.insert.insert(grid, op, data, {
					posTr : endTr.length ? endTr.prev() : tr.parent().children(':last'),
					position : "after",
					isScroll : false,
					// 添加新增行的同级行，需定义插入位置
					posIndex: grid.isNewRow(tr) ? (rowData._index + 1) : null
				});
				// 计数节点的子节点个数
				if (isChild) {
					// 添加父级的treeNo
					data._treeNo = rowData._treeNo + "." + data.rowIdx;
					// 计数子节点的个数
					rowData._childCount ? rowData._childCount++ : (rowData._childCount = 1);
					// 父节点是否是选中状态
					rowData._selected && (isSelectParent = true);
				} else {
					// 添加父级的treeNo
					data._treeNo = rowData._treeNo.substring(0, rowData._treeNo.lastIndexOf(".") + 1) + data.rowIdx;
					var parentData = op._treeStorage.getParent(rowData),parentData=parentData?parentData.data:null,
						endTrData = endTr.length && grid.getRowData(endTr);
					// 计数子节点的个数
					parentData && (parentData._childCount ? parentData._childCount++ : (parentData._childCount = 1));
					// 父节点是否是选中状态
					parentData && parentData._selected && (isSelectParent = true);
					// 定位新增节点的位置
					data._tempPos = (endTrData && endTrData._deep == rowData._deep) ? treeGrid.getID(rOp.field, endTrData) : "last";
				}
				// 父节点选中，才会执行父节点状态计算
				isSelectParent && treeGrid.selectParent(grid, op, grid.getRow(data.rowIdx), true, null, false);
			}
		},
		// 获取深度获取节点tr
		getPosTr : function(tr, deep, isChild) {
			if (tr.length) {
				var curDeep = treeGrid.getDeep(tr);
				if (curDeep == deep || curDeep < deep)
					return tr;
				else {
					return isChild ? tr : arguments.callee(tr.next(), deep);
				}
			}
			return tr;
			// return tr.length ? (treeGrid.getDeep(tr) == deep ? tr : (isChild
			// ? tr: arguments.callee(tr.next(),deep))) : tr;
		},
		// 上下文菜单的逻辑效验
		checkMenu : function(cell, cMenu, list, grid) {
			if (cell) {
				var a = cell.children('a'), menus = list.find(' > ul > li'), tr = cell.parents('tr:first'), deep = this.getDeep(tr), isDel = tr.hasClass(Const.deleted.css);
				menus.filter('.add_child').toggleClass('hide', deep >= grid.op.rowRenderOp.loadDeep || isDel);
				menus.filter('.add').toggleClass('hide', isDel);
			}
		},
		// 移除节点
		removeNode : function(cell, op, grid) {
			var store = op.Storage, tr = grid.getCellRow(cell), 
				rowData = grid.getRowData(tr), 
				isDel = !store.isDeleted(rowData),
				isSelect = store.isSelected(rowData);
			isSelect || tr.data("_isRemove", true);
			rowData._selectedChilds && (rowData._selectedChilds = 0);
			IGrid.Operation.del.delRow(tr, isDel, grid);
			// 设置子节点删除状态
			this.handleChild(tr, function(nodeTr) {
				nodeTr.data("_isRemove", true);
				IGrid.Operation.del.delRow(nodeTr, isDel, grid);
			});
			if (op.Storage.isNew(rowData) && isDel) {
				op._treeStorage.destroy(rowData);
			} else
				op._treeStorage.remove(rowData, isDel);
		},
		// 树数据排序
		sort : function(sortField, sort, cell) {
			var op = this.op, roots = treeGrid.sortNode(treeGrid.buildDataTree(op.Storage.store(), op), sortField, sort);
			op.Storage.store(treeGrid.buildTreeList(roots, op.rowRenderOp));
			dynamicLoad.treeLoad(this, op);
			return false;
		},
		// 子节点数据排序
		sortNode : function(nodes, sortField, sort) {
			nodes = Ccay.DataHelper.sort(sortField, sort, nodes);
			for (var i = 0, node; node = nodes[i]; i++) {
				if (node._childs && node._childs.length)
					arguments.callee(node._childs, sortField, sort)
			}
			return nodes;
		},
		// /获取根节点
		getRoots : function(datas, op) {
			var treeData = this.buildDataTree(datas, op);
			$.each(treeData, function(i, n) {
						n._childs = null;
					});
			return treeData;
		},
		getDeep : function(tr) {
			return tr.attr('deep') * 1;
		},
		// 子节点处理方法
		handleChild : function(tr, fnHandle) {
			var parentDeep = this.getDeep(tr);
			tr = tr.next();
			if (tr.length) {
				var deep = this.getDeep(tr);
				while (parentDeep < deep) {
					var nextTr = tr.next();
					fnHandle(tr, deep);
					if (nextTr && nextTr.length) {
						tr = nextTr;
						deep = this.getDeep(tr);
					} else
						return;
				}
			}
		},
		// 父节点处理方法
		handleParent : function(tr, fnHandle, op) {
			var parentDeep = this.getDeep(tr);
			tr = tr.prev();

			if (tr.length) {
				var deep = this.getDeep(tr);
				while (parentDeep > 0) {
					if (deep < parentDeep) {
						parentDeep--;
						fnHandle(tr, deep);
					}
					tr = tr.prev();
					if (tr && tr.length)
						deep = this.getDeep(tr);
					else
						return;
				}
			}
		},
		// 创建节点模板
		buildNodeTmpl : function(col, rOp, op) {
			var tmpl = ["<span class='igrid-tree' style='margin-left:${#_deep? _deep*10 : 0}px'>"];

			if (rOp.select) {
				tmpl.push("<span class='tree-chk ", rOp.select, "' eno='nodeSelect'>&nbsp;</span>");
				op.handler.click.add("nodeSelect", this.nodeSelect);
			}
			tmpl.push("<span ${#data._hasChild ? 'eno=toggleTree' : ''} ${#data._lazyLoad ? '_lz=' +", rOp.field, " :''} ${#Ccay.UI.IGrid.setCustomIcon(data, _grid)}</span>");
			tmpl.push("</span><span class='child-render'>", (col.content || "${" + col.field + "}"), "</span>");
			col.content = tmpl.join('');
		},
		// 节点选中
		nodeSelect : function(e, tag, grid) {
			e && e.stopPropagation();
			var multi = tag.hasClass('multi'), op = grid.op, 
				tr = grid.getCellRow(tag),rowData = grid.getRowData(tr), 
				selected = !op.Storage.isSelected(rowData), rOp = op.rowRenderOp, 
				gridSelect = IGrid.innerColumn.gridSelect;
			if (multi) {
				// 若存在半选状态则，则进行标示
				if (tr.hasClass(Const.halfSelected.css)) {
					tr.data("_selected", {"half": selected});
					treeGrid.halfRowSelected(tr, false, grid);
				} else {
					tr.data("_selected", {"all": selected});
				}
				// 设置dom树中该节点的状态
				gridSelect.rowSelected(tr, selected, grid);
				// 设置dom树中该节点的子节点的状态
				treeGrid.handleChild(tr, function(nodeTr) {
					if (nodeTr.hasClass(Const.halfSelected.css)) {
						treeGrid.halfRowSelected(nodeTr, false, grid);
					} 
					gridSelect.rowSelected(nodeTr, selected, grid);
				});
				// 设置数据集中的该节点已经父节点的状态
				if (!op.Storage.isNew(rowData)) {
					op._treeStorage.setSelected(rowData, selected);
				}
			} else {
				// 消除所有的半选状态
				treeGrid.removeHalfSelected(tr, selected, grid);
				gridSelect.singlerSelected(e, tr, selected, grid);
			}
			treeGrid.selectParent(grid, op, tr, multi, selected);
		},
		selectParent: function (grid, op, tr, multi, selected, isCount) {
			// 判断父节点是否也有选择状态
			if (op.rowRenderOp.selectParent) {
				var tempTr = tr, isGoHandle;
				treeGrid.handleParent(tr, function(nodeTr, deep) {
					// 设置选中的状态
					if (multi) {
						if (isGoHandle != false) {
							// 添加新节点是，判断是否计算父节点的状态
							if (isCount == false && tempTr.data("_selected")) {
								isCount = true;
							}
							isGoHandle = treeGrid.multiParentSelected(nodeTr, tempTr, grid, isCount);
							tempTr = nodeTr;
						}
					} else {
						treeGrid.halfRowSelected(nodeTr, selected, grid);
					}
				});
			}
		},
		// 多选状态，父节点同步
		multiParentSelected: function (tr, childTr, grid, isCount) {
			var parentData = grid.getRowData(tr), op = grid.op, rOp = op.rowRenderOp,
				gridSelect = IGrid.innerColumn.gridSelect,
				tempChildSelected = childTr.data("_selected");
			// 获取子节点
			(parentData._selectedChilds == null) && (parentData._selectedChilds = 0);
			if (isCount != false) {
				// 通过选择状态，进行父节点的选中子节点个数的计算
				if (!tempChildSelected["notChange"]) {
					if (tempChildSelected["half"] == null) {
						tempChildSelected["all"] ? parentData._selectedChilds++ : parentData._selectedChilds--;
					} else {
						tempChildSelected["half"] ? parentData._selectedChilds += 0.5 : parentData._selectedChilds -= 0.5;
						childTr.hasClass(Const.selected.css) && childTr.data("_selected", {"all": true});
					}
				} else {
					childTr.data("_selected", tempChildSelected["notChange"]);
					return false;
				}
			}
			var selectedChilds = parentData._selectedChilds;
			if (selectedChilds) {
				// 判断是否子节点全部选中，否则半选状态
				if (parentData._childCount == selectedChilds) {
					// 若存在半选状态则清除，并缓存半选状态，并更改节点状态标示
					if (tr.hasClass(Const.halfSelected.css)) {
						tr.data("_selected", {"half": true});
						treeGrid.halfRowSelected(tr, false, grid);
					} else {
						tr.data("_selected", {"all": true});
					}
					gridSelect.rowSelected(tr, true, grid);
				} else {
					if (tr.hasClass(Const.halfSelected.css)) {
						// 若存在半选状态，则将节点的状态标示清除，这样将不会再进行父父级节点选中子节点的计算
						tr.data("_selected", {"notChange": tr.data("_selected")});
					} else {
					// 若存在全选状态则清除，并缓存全选状态，并更改节点状态标示
						if (tr.hasClass(Const.selected.css)) {
							tr.data("_selected", {"half": false});
							gridSelect.rowSelected(tr, false, grid);
						} else {
							tr.data("_selected", {"half": true});
						}
						treeGrid.halfRowSelected(tr, true , grid);
					}
				}
			} else {
				// 未选中任何子节点的，则将状态全部清除
				tr.data("_isRemove", true);
				if (tr.hasClass(Const.halfSelected.css)) {
					tr.data("_selected", {"half": false});
					treeGrid.halfRowSelected(tr, false, grid);
				} else if (tr.hasClass(Const.selected.css)) {
					tr.data("_selected", {"all": false});
					gridSelect.rowSelected(tr, false, grid);
				}
			}
		},
		// 移除所有的半选状态
		removeHalfSelected: function (tr, selected, grid) {
			grid.getSelectRows(true, "." + Const.halfSelected.css).each(function(i) {
				treeGrid.halfRowSelected($(this), false, grid);
			});
		},
		// 设置半选状态
		halfRowSelected: function (tr, selected, grid) {
			grid.op._treeStorage.setHalfSelected(grid.getRowData(tr), selected, tr);
		},
		// 通过节点ID定位节点
		fixedNode: function (grid, nodeId, isReload, isExpand) {
			var nodeData = treeGrid.getNodeInfoByField(grid, nodeId, true),
				op = grid.op, nodeDataIdx, nodeTr, nodeTag, nodeTrHeight, 
				nodeTrTop, bodyPanel, bodyHeight;
			if (nodeData) {
				nodeDataIdx = nodeData.rowIdx;
				// 当前节点存在dom中，则直接进行加载子节点，否则先加载父节点，在加载子节点
				if (grid.getRowData(nodeDataIdx) == nodeData) {
					nodeTag = grid.getRow(nodeDataIdx).find("span.tree-icon");
					// 判断是否展开子节点
					if (isReload) {
						// 清除dom树中的子节点
						dynamicLoad.removeChild(grid, op, nodeData._deep, nodeDataIdx + 1, false);
						// 重新加载子节点
						nodeTag.toggleClass('tree-close', false);
						dynamicLoad.bindChild(grid, op, nodeData, nodeTag, Ccay.DataHelper.getObj(op.rowRenderOp.field, nodeData), nodeDataIdx + 1, true);
					} else {
						if (isExpand && nodeTag.hasClass('tree-close')) {
							nodeTag.removeClass("tree-close");
							// 加载子节点
							dynamicLoad.loadChild(nodeTag, grid);
						}
					}
				} else {
					var parentNodes = nodeData._parents, pNodeData, isLoad;
					// 循环父节点，添加子节点数据
					for (var i = 0, pNode; pNode = parentNodes[i]; i++) {
						pNodeData = pNode.data, treeStorage = op._treeStorage;
						// 若父节点没有打开，则加载子节点
						if (!pNodeData._opened) {
							// 将该节点的父节点下的子节点全部放入到dom数据集中
							var childs = treeStorage.toggleNode(pNodeData, true);
							childs.unshift(pNodeData.rowIdx + 1, 0);
							Array.prototype.splice.apply(op.Storage.store(), childs);
						}
					}
					// 加载当前节点
					if (isReload) {
						dynamicLoad.bindChild(grid, op, nodeData, nodeTag, Ccay.DataHelper.getObj(op.rowRenderOp.field, nodeData), nodeDataIdx + 1, true);
					} else {
						// 添加子节点
						if (isExpand && nodeData._childCount && !nodeData._opened) {
							nodeData._opened = true;
							var childs = treeStorage.toggleNode(nodeData, true);
							childs.unshift(nodeDataIdx + 1, 0);
							Array.prototype.splice.apply(op.Storage.store(), childs);
						}
						dynamicLoad.treeLoad(grid, op);
					}
				}
				// 不重新加载子节点，则定位节点
				if (!isReload) {
					// 计算节点位置
					nodeTr = grid.getRow(nodeData.rowIdx);
					nodeTrHeight = nodeTr.height();
					nodeTrTop = nodeTr.position().top + nodeTrHeight;
					bodyPanel = grid.getBodyPanel();
					bodyHeight = bodyPanel.height();
					// 将节点滚动定位到中间位置
					if (nodeTrTop < 0 || nodeTrTop > bodyHeight) {
						bodyPanel.scrollTop(grid.getRowIndex(nodeTr) * nodeTrHeight - bodyHeight / 2);
					}
					// 焦点定位到该节点
					grid.setFocusRow(nodeTr);
				}
			}
		},
		// 重新加载节点
		reloadChildNodes: function (grid, nodeId) {
			var node = treeGrid.getNodeInfoByField(grid, nodeId, false, true);
			if (node) {
				// 清除子节点，新增节点不清除
				if (node.count) {
					var childs = node.childs;
					for (var nodeIdx in childs) {
						if (!childs[nodeIdx].data._inserted) {
							delete node.childs[nodeIdx];
							node.count--;
						}
					}
				}
				treeGrid.fixedNode(grid, nodeId, true);
			}
		},
		// 通过节点ID获取节点信息
		getNodeInfoByField: function (grid, fieldValue, isGetParents, isNodeInf) {
			var op = grid.op, treeStorage = op._treeStorage, nodeData = fieldValue;
			// fieldValue参数不是数据对象时，则通过该值获取数据对象
			if (!$.isPlainObject(fieldValue)) {
				// 在dom树中查找节点是否存在，若存在，则定位到该节点；否则在数据集中查找
				var tempNode = op.Storage.findOne(function (item, i) {
					return (fieldValue == treeStorage.getKey(item)) ? true : false;
				});
				if (!tempNode) {
					// 在数据集中查找节点是否存在，若存在，则查找该节点的父节点，然后判断父节点是否在dom树中，若存在，则展开该父节点的子节点，然后定位到该子节点
					tempNode = treeStorage.findOne(function (item ,node, i, count) {
						return (fieldValue == this.getKey(item)) ? true : false;
					});
				}
				nodeData = tempNode || null;
			}
			if (nodeData) {
				isGetParents && (nodeData._parents = treeGrid.getParentNodes(treeStorage, nodeData));
				isNodeInf && (nodeData = treeStorage.at(nodeData));
			}
			return nodeData;
		},
		// 获取所有的父节点
		getParentNodes: function (treeStorage, nodeData, parents) {
			var parentNode = treeStorage.getParent(nodeData);
			if (parentNode) {
				if (parents) {
					parents.unshift(parentNode);
				} else {
					parents = [parentNode];
				}
				arguments.callee(treeStorage, parentNode, parents);
			}
			return parents;
		},
		// 将新增数据插入到指定位置
		insertToChilds: function (nodeData, newChilds, childs, treeStorage) {
			if (newChilds.length) {
				// 获取父节点ID
				var pid = treeStorage.getKey(nodeData), tempPos, newParentId, dataPos, childKey;
				// 遍历新增数据
				for (var i = 0, newChild; newChild = newChilds[i]; i++) {
					dataPos = null;
					tempPos = newChild._tempPos;
					newParentId = treeStorage.getParentKey(newChild);
					// 添加子节点，则在所有子节点前插入
					if (!tempPos && newParentId == pid) {
						childs.unshift(newChild);
					} else {
						// 添加子节点，则在指定子节点前插入
						for (var c = 0, tempChild; tempChild = childs[c]; c++) {
							childKey = treeStorage.getKey(tempChild);
							// 添加子节点，则在父节点后插入，否则在指定位置插入
							if (!tempPos && newParentId == childKey) {
								dataPos = c + 1;
							} else if (tempPos == childKey) {
								dataPos = c || 1;
							}
							if (dataPos) {
								childs.splice(dataPos, 0, newChild);
								break;
							}
						}
					}
				}
			}
			return childs;
		}
	};

	var dynamicLoad = {
		updateTotal : function(op) {
			op.lazyLoad && (op.pagerOp.pageInf.totalRows = op.Storage.len());
		},
		loadChild : function(nodeTag, grid) {
			var op = grid.op, rOp = op.rowRenderOp, reload, isLoad = nodeTag.attr('_lz'), 
				isClose = nodeTag.hasClass('tree-close'), tr = nodeTag.parents('tr:first'), 
				deep = treeGrid.getDeep(tr), index = grid.getRowIndex(tr), nodeData = op.Storage.at(index),
				pid = Ccay.DataHelper.getObj(rOp.field, nodeData);
			delete nodeData._lazyLoad;
			if (isClose) {
				delete nodeData._opened;
				this.removeChild(grid, op, deep, index + 1);
			} else {
				if (rOp.onlyExpandDeep != null && deep <= rOp.onlyExpandDeep) {
					this.onlyExpandNode(grid, op, op._treeStorage.dataset.childs, nodeData._treeNo.split("."), 0);
				}
				nodeData._opened = true;
				this.bindChild(grid, op, nodeData, nodeTag, pid, nodeData.rowIdx + 1, isLoad);
			}
		},
		onlyExpandNode: function (grid, op, rootDatas, rootNo, deep) {
			var rootData;
			// 循环遍历根节点
			for (var rootIdx in rootDatas) {
				rootData = rootDatas[rootIdx].data;
				// 判断根节点是否展开，展开需合闭
				if (rootData._opened) {
					// 若不是展开节点的父节点，则需要闭合
					if (rootData._treeNo.split(".")[deep] != rootNo[deep]) {
						delete rootData._opened;
						this.removeChild(grid, op, rootData._deep, rootData.rowIdx + 1);
					} else if (rootDatas[rootIdx].count > 1) {
						// 判断下一级节点的关闭
						this.onlyExpandNode(grid, op, rootDatas[rootIdx].childs, rootNo, deep + 1);
					}
				}
			}
		},
		removeChild : function(grid, op, deep, index, isReload) {
			var num = 0, nextData = op.Storage.at(index), nextDeep = nextData ? nextData._deep : 0;

			while (nextDeep > deep) {
				nextData = op.Storage.at(index + (++num));
				nextDeep = nextData ? nextData._deep : 0;
			}
			if (num) {
				op.Storage.dataset.splice(index, num);
				(isReload != false) && this.treeLoad(grid, op);
			}
		},
		initRowRenderAjax : function (rOp, nodeData, pid, fnSuccess, fnError) {
			if (rOp.ajax || rOp.url) {
				var ajax = $.extend({}, rOp.ajax) || {url: rOp.url};
				if (ajax.url) {
					if(ajax.url.indexOf('{0}') > 0)
						ajax.url = ajax.url.formatText(pid);
					else
						ajax.url = ajax.url.formatField(nodeData);
				}
				ajax.success = function(result) {
					fnSuccess && fnSuccess(result.result || result);
				};
				ajax.error = function(textStatus, errorThrown, responseText, status) {
					nodeData._opened = false;
					fnError && fnError(textStatus, errorThrown, responseText, status);
				};
				Ccay.UI.ajax(ajax);
			}
		},
		bindChild : function(grid, op, nodeData, nodeTag, pid, index, isLoad) {
			var node = op._treeStorage.at(nodeData);
			if (isLoad) {
				dynamicLoad.initRowRenderAjax(op.rowRenderOp, nodeData, pid, function (data) {
					dynamicLoad.appendChild(grid, op, nodeTag, index, node, data);
				});
				return false;
			}
			this.appendChild(grid, op, nodeTag, index, node);
		},
		appendChild : function(grid, op, nodeTag, index, node, addData) {
			var treeStorage = op._treeStorage, childs;
			if (addData && addData.length) {
				treeStorage.insert(node, addData);
				node.data._childCount = node.count;
				//childs = childs.concat(addData);
			}
			childs = treeStorage.toggleNode(node, true);
			if (childs.length) {
				node.data._opened = true;
//				childs.unshift(index, 0);
//				Array.prototype.splice.apply(op.Storage.store(), childs);
				var storeList = op.Storage.store();
				var newChilds = storeList.splice(index,storeList.length);
				Array.prototype.push.apply(storeList, childs);
				Array.prototype.push.apply(storeList, newChilds);
				this.treeLoad(grid, op);
			} else {
				delete node.data._lazyLoad;
				delete node.data._hasChild;
				delete node.data._opened;
				nodeTag && nodeTag.length && nodeTag.removeAttr("_lz").removeAttr("eno").removeClass("tree-open");
			}
		},
		treeLoad : function(grid, op,data) {
			op._scrollLoading = true;
			data && op.Storage.store(data);
			grid.reload();
			delete op._scrollLoading;
		}
	};
	//判断树节点的展开状态(模板中使用)
	IGrid.checkTreeNode = function(data) {
		var css = "";
		if (data._hasChild || data._lazyLoad) {
			css = " tree-open";
			if (!data._opened)
				css += " tree-close";
		}
		return css;
	}
	
	// 提供用户自定义层级图标
	IGrid.setCustomIcon = function (data, grid) {
		var customIcon = grid.op.rowRenderOp && grid.op.rowRenderOp.customIcon, 
			css = "", iconStyle;
		if (data._hasChild || data._lazyLoad) {
			css = "tree-open";
			if (!data._opened)
				css += " tree-close";
		}
		if (customIcon) {
			iconStyle = (typeof customIcon == "function") ? customIcon.call(grid, data) : (customIcon[data._deep] || customIcon["def"]);
			if (css) {
				iconStyle += (css.indexOf("close") > 0) ? "-close" : "-open";
			}
		}
		return "class='tree-icon {0}'>{1}".formatText(iconStyle ? css : "tree-node " + css, iconStyle ? "<a class='" + iconStyle + "'></a>" : "");
	}
	
	Ccay.UI.XControl.extendIManager("XGrid", {
		treeFilter:function(fields,fnFilter,copy,fnHandler){
			return this.op._treeStorage.nodeFilter(fields,fnFilter,copy,fnHandler);
		},
		treeLoad:function(data){
			dynamicLoad.treeLoad(this,this.op,data);
			dynamicLoad.updateTotal(this.op);
			this.getBodyPanel().scrollTop(0);
		},
		getNodeByField: function (fieldValue) {
			treeGrid.getNodeInfoByField(this, fieldValue);
		},
		goToNode: function (fieldValue, isExpand) {
			treeGrid.fixedNode(this, fieldValue, false, isExpand);
		},
		reloadChildNodes: function (fieldValue) {
			// 先定位节点，然后重新加载子节点
			treeGrid.reloadChildNodes(this, fieldValue);
		}
	});
	
})(Ccay.UI.IGrid, Ccay.UI.IGrid.Const);
